package com.promise.jokerdream.ui.drawer

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.gestures.awaitEachGesture
import androidx.compose.foundation.gestures.awaitFirstDown
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import kotlinx.coroutines.launch
import kotlin.math.abs

/**
 * 全屏边缘滑动抽屉组件
 * 支持从屏幕任何位置左右滑动打开/关闭抽屉，不会干扰主内容的垂直滑动
 */
@Composable
fun FullScreenEdgeSwipeDrawer(
    drawerWidth: Dp,
    isDrawerOpen: Boolean,
    enableGesture: Boolean = true,
    onDrawerStateChanged: (Boolean) -> Unit,
    onOpenDrawer: () -> Unit,
    onCloseDrawer: () -> Unit,
    drawerContent: @Composable () -> Unit,
    content: @Composable () -> Unit
) {
    val density = LocalDensity.current
    val coroutineScope = rememberCoroutineScope()
    
    // 使用 Animatable 来处理动画
    val maxOffset = 0f
    val minOffset = with(density) { -drawerWidth.toPx() }
    val drawerOffset = remember { Animatable(minOffset) }
    
    // 移除边缘检测限制，全屏响应
    
    // 最小拖拽距离阈值
    val dragThreshold: Float = with(density) { 10.dp.toPx() }
    
    // 手势状态
    var isDragging by remember { mutableStateOf(false) }
    var startX by remember { mutableStateOf(0f) }
    var startY by remember { mutableStateOf(0f) }
    var dragStarted by remember { mutableStateOf(false) }
    var lastDragDirection by remember { mutableStateOf(0f) } // 记录最后的滑动方向
    
    // 同步抽屉状态与偏移量
    LaunchedEffect(isDrawerOpen) {
        drawerOffset.animateTo(
            targetValue = if (isDrawerOpen) maxOffset else minOffset,
            animationSpec = spring(
                dampingRatio = 0.9f,  // 接近临界阻尼，减少震荡
                stiffness = 300f      // 提高刚度，加快响应
            )
        )
    }
    
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(enableGesture) {
                if (!enableGesture) {
                    return@pointerInput
                }

                awaitEachGesture {
                    // 等待按下
                    val down = awaitFirstDown(requireUnconsumed = false)
                    startX = down.position.x
                    startY = down.position.y
                    isDragging = false
                    dragStarted = false
                    lastDragDirection = 0f
                    
                    var pointer = down
                    
                    do {
                        val event = awaitPointerEvent()
                        pointer = event.changes.first()
                        
                        if (pointer.pressed) {
                            val currentX = pointer.position.x
                            val currentY = pointer.position.y
                            val totalDragX = abs(currentX - startX)
                            val totalDragY = abs(currentY - startY)
                            
                            // 检查是否需要开始拖拽
                            if (!isDragging && !dragStarted) {
                                if (totalDragX > dragThreshold || totalDragY > dragThreshold) {
                                    if (totalDragX > totalDragY * 1.2f) {
                                        // 水平拖拽明显，开始抽屉操作
                                        isDragging = true
                                        dragStarted = true
                                    } else {
                                        // 垂直拖拽明显，退出不处理
                                        break
                                    }
                                }
                            }
                            
                            // 抽屉拖拽处理
                            if (isDragging && dragStarted) {
                                val deltaX = currentX - pointer.previousPosition.x
                                val newOffset = (drawerOffset.value + deltaX).coerceIn(minOffset, maxOffset)
                                
                                // 记录最后的滑动方向
                                if (abs(deltaX) > 1f) { // 只有明显移动时才更新方向
                                    lastDragDirection = deltaX
                                }
                                
                                coroutineScope.launch {
                                    drawerOffset.snapTo(newOffset)
                                }
                                pointer.consume()
                            }
                        }
                    } while (pointer.pressed)
                    
                    // 拖拽结束处理
                    if (dragStarted) {
                        // 根据最后的滑动方向决定抽屉最终状态
                        val targetOffset = if (lastDragDirection > 0) {
                            maxOffset  // 最后向右滑动，展开抽屉
                        } else {
                            minOffset  // 最后向左滑动，收起抽屉
                        }
                        
                        coroutineScope.launch {
                            drawerOffset.animateTo(
                                targetValue = targetOffset,
                                animationSpec = spring(
                                    dampingRatio = 0.9f,  // 接近临界阻尼，减少震荡
                                    stiffness = 400f      // 提高刚度，加快响应
                                )
                            )
                            
                            val isNowOpen = targetOffset == maxOffset
                            if (isNowOpen != isDrawerOpen) {
                                onDrawerStateChanged(isNowOpen)
                            }
                        }
                    }
                }
            }
    ) {
        // 主内容
        content()
        
        // 遮罩层（当抽屉打开时）
        val currentOffset by drawerOffset.asState()
        if (isDrawerOpen || currentOffset > minOffset) {
            val alpha = ((currentOffset - minOffset) / (maxOffset - minOffset)).coerceIn(0f, 1f) * 0.5f
            Box(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.Black.copy(alpha = alpha))
                    .clickable(
                        interactionSource = remember { MutableInteractionSource() },
                        indication = null,  // 移除水波纹效果
                        onClick = { onCloseDrawer() }
                    )
            )
        }
        
        // 抽屉内容
        Box(
            modifier = Modifier
                .fillMaxHeight()
                .width(drawerWidth)
                .offset(x = with(density) { currentOffset.toDp() })
                .background(MaterialTheme.colorScheme.surface)
                .zIndex(1f)
        ) {
            drawerContent()
        }
    }
}
